]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
status/keyboard: Add input source switching per window
authorRui Matos <tiagomatos@gmail.com>
Wed, 9 Jan 2013 01:01:33 +0000 (02:01 +0100)
committerRui Matos <tiagomatos@gmail.com>
Mon, 14 Jan 2013 10:11:00 +0000 (11:11 +0100)
If the setting is enabled, we record the last activated input source
for the currently focused window and switch to it when focusing back
that window. The Overview is considered a window for this purpose.

https://bugzilla.gnome.org/show_bug.cgi?id=691414

js/ui/status/keyboard.js

index 590d2eeff3cb27338f0fa4d3cf89c7832c6484a6..f0914184666981b4fdec9254718997fe36e801eb 100644 (file)
@@ -366,6 +366,13 @@ const InputSourceIndicator = new Lang.Class({
         this._sessionUpdated();
 
         this.menu.addSettingsAction(_("Region and Language Settings"), 'gnome-region-panel.desktop');
+
+        this._sourcesPerWindow = false;
+        this._focusWindowNotifyId = 0;
+        this._overviewShowingId = 0;
+        this._overviewHiddenId = 0;
+        this._settings.connect('changed::per-window', Lang.bind(this, this._sourcesPerWindowChanged));
+        this._sourcesPerWindowChanged();
     },
 
     _sessionUpdated: function() {
@@ -431,6 +438,8 @@ const InputSourceIndicator = new Lang.Class({
                 this._mruSources = currentSource.concat(this._mruSources);
                 break;
             }
+
+        this._changePerWindowSource();
     },
 
     _inputSourcesChanged: function() {
@@ -704,6 +713,82 @@ const InputSourceIndicator = new Lang.Class({
         }
     },
 
+    _getNewInputSource: function(current) {
+        for (let i in this._inputSources) {
+            let is = this._inputSources[i];
+            if (is.type == current.type &&
+                is.id == current.id)
+                return is;
+        }
+        return this._currentSource;
+    },
+
+    _getCurrentWindow: function() {
+        if (Main.overview.visible)
+            return Main.overview;
+        else
+            return global.display.focus_window;
+    },
+
+    _setPerWindowInputSource: function() {
+        let window = this._getCurrentWindow();
+        if (!window)
+            return;
+
+        if (!window._inputSources) {
+            window._inputSources = this._inputSources;
+            window._currentSource = this._currentSource;
+        } else if (window._inputSources == this._inputSources) {
+            window._currentSource.activate();
+        } else {
+            window._inputSources = this._inputSources;
+            window._currentSource = this._getNewInputSource(window._currentSource);
+            window._currentSource.activate();
+        }
+    },
+
+    _sourcesPerWindowChanged: function() {
+        this._sourcesPerWindow = this._settings.get_boolean('per-window');
+
+        if (this._sourcesPerWindow && this._focusWindowNotifyId == 0) {
+            this._focusWindowNotifyId = global.display.connect('notify::focus-window',
+                                                               Lang.bind(this, this._setPerWindowInputSource));
+            this._overviewShowingId = Main.overview.connect('showing',
+                                                            Lang.bind(this, this._setPerWindowInputSource));
+            this._overviewHiddenId = Main.overview.connect('hidden',
+                                                           Lang.bind(this, this._setPerWindowInputSource));
+        } else if (!this._sourcesPerWindow && this._focusWindowNotifyId != 0) {
+            global.display.disconnect(this._focusWindowNotifyId);
+            this._focusWindowNotifyId = 0;
+            Main.overview.disconnect(this._overviewShowingId);
+            this._overviewShowingId = 0;
+            Main.overview.disconnect(this._overviewHiddenId);
+            this._overviewHiddenId = 0;
+
+            let windows = global.get_window_actors().map(function(w) {
+                return w.meta_window;
+            });
+            for (let i = 0; i < windows.length; ++i) {
+                delete windows[i]._inputSources;
+                delete windows[i]._currentSource;
+            }
+            delete Main.overview._inputSources;
+            delete Main.overview._currentSource;
+        }
+    },
+
+    _changePerWindowSource: function() {
+        if (!this._sourcesPerWindow)
+            return;
+
+        let window = this._getCurrentWindow();
+        if (!window)
+            return;
+
+        window._inputSources = this._inputSources;
+        window._currentSource = this._currentSource;
+    },
+
     _containerGetPreferredWidth: function(container, for_height, alloc) {
         // Here, and in _containerGetPreferredHeight, we need to query
         // for the height of all children, but we ignore the results